﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Windows.Networking.BackgroundTransfer;
using Windows.Storage;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;

namespace Metro_Calc
{
    public sealed partial class BlankPage : Page
    {
        private List<DownloadOperation> activeDownloads;
        private CancellationTokenSource cts;

        public void resetCalc()
        {
            Core.Operand = 0;
            this.CalcType.Text = "";
            this.CalcResult.Text = "0";
            this.CalcNumber.Text = "";
            Core.IsCalculated = false;
            Core.ExistsDot = false;
        }
        public void changeOperand(Int32 newOperand)
        {
            Core.Operand = newOperand;
            switch(newOperand)
            {
                case 0:
                    {
                        this.CalcType.Text = "";
                        this.CalcNumber.Text = this.CalcResult.Text;
                        this.CalcResult.Text = "0";
                        Core.ExistsDot = false;
                    } break;
                case 1:
                    {
                        this.CalcType.Text = "+";
                        this.CalcNumber.Text = this.CalcResult.Text;
                        this.CalcResult.Text = "0";
                        Core.ExistsDot = false;
                    } break;
                case 2:
                    {
                        this.CalcType.Text = "-";
                        this.CalcNumber.Text = this.CalcResult.Text;
                        this.CalcResult.Text = "0";
                        Core.ExistsDot = false;
                    } break;
                case 3:
                    {
                        this.CalcType.Text = "x";
                        this.CalcNumber.Text = this.CalcResult.Text;
                        this.CalcResult.Text = "0";
                        Core.ExistsDot = false;
                    } break;
                case 4:
                    {
                        this.CalcType.Text = "÷";
                        this.CalcNumber.Text = this.CalcResult.Text;
                        this.CalcResult.Text = "0";
                        Core.ExistsDot = false;
                    } break;
                case 5:
                    {
                        this.CalcType.Text = "=";
                    } break;
                default:
                    {
                    } break;
            }
        }
        public void addDigit(String newDigit)
        {
            /**
             * Fügt eine Ziffer hinzu
             */
            if (this.CalcResult.Text.Length == 1 && this.CalcResult.Text == "0")
                this.CalcResult.Text = "";

            this.CalcResult.Text += newDigit;
        }

        private async void loadBingWallpaper()
        {
            DownloadOperation download = null;
            try
            {
                Core.BingWallpaperXMLUrl = string.Format(Core.BingWallpaperXMLUrl, 1, "de-DE");

                Uri source = new Uri(Core.BingWallpaperImgUrl);
                string destination = "metrocalcbingwallpaperxml.dat";

                StorageFile destinationFile = await KnownFolders.PicturesLibrary.CreateFileAsync(destination, CreationCollisionOption.GenerateUniqueName);

                BackgroundDownloader downloader = new BackgroundDownloader();
                download = downloader.CreateDownload(source, destinationFile);

                // Attach progress and completion
                HandleDownloadAsync(download, true);
            }
            catch (Exception ex)
            {
                //LogException("Download Error", ex);
            }
        }
        private void DownloadProgress(DownloadOperation download)
        {
            if (download.Progress.TotalBytesToReceive > 0)
            {
                double percent = download.Progress.BytesReceived * 100
                    / download.Progress.TotalBytesToReceive;
                MessageDialog msg1 = new MessageDialog(" - Transfered bytes: " + download.Progress.BytesReceived + " of "
                    + download.Progress.TotalBytesToReceive + ", " + percent + "%");
                msg1.ShowAsync();
                //MarshalLog(" - Transfered bytes: " + download.Progress.BytesReceived + " of "
                //    + download.Progress.TotalBytesToReceive + ", " + percent + "%");
            }
            else
            {
                MessageDialog msg1 = new MessageDialog(" - Transfered bytes: " + download.Progress.BytesReceived);
                msg1.ShowAsync();
                //MarshalLog(" - Transfered bytes: " + download.Progress.BytesReceived);
            }

            if (download.Progress.HasRestarted)
            {
                MessageDialog msg1 = new MessageDialog(" - Download restarted");
                msg1.ShowAsync();
                //MarshalLog(" - Download restarted");
            }

            if (download.Progress.HasResponseChanged)
            {
                MessageDialog msg1 = new MessageDialog(" - Response updated; Header count: "
                    + download.GetResponseInformation().Headers.Count);
                msg1.ShowAsync();
                // We've received new response headers from the server.
                //MarshalLog(" - Response updated; Header count: "
                //    + download.GetResponseInformation().Headers.Count);

                // If you want to stream the response data this is a good time to start.
                download.GetResultStreamAt(0);
            }
        }
        private async void HandleDownloadAsync(DownloadOperation download, bool start)
        {
            try
            {
                activeDownloads.Add(download); // Store the download so we can pause/resume.

                Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(DownloadProgress);
                if (start)
                {
                    // Start the download and attach a progress handler.
                    await download.StartAsync().AsTask(cts.Token, progressCallback);
                }
                else
                {
                    // The download was already running when the application started, re-attach the progress handler.
                    await download.AttachAsync().AsTask(cts.Token, progressCallback);
                }

                ResponseInformation response = download.GetResponseInformation();
                MessageDialog msg = new MessageDialog("Completed: " + download.Guid + ", Status Code: " + response.StatusCode);
                await msg.ShowAsync();
                //Log("Completed: " + download.Guid + ", Status Code: " + response.StatusCode);
            }
            catch (TaskCanceledException)
            {
                MessageDialog msg1 = new MessageDialog("Download cancelled.");
                msg1.ShowAsync();
                //Log("Download cancelled.");
            }
            catch (Exception ex)
            {
                MessageDialog msg2 = new MessageDialog("Error");
                msg2.ShowAsync();
                //LogException("Error", ex);
            }
            finally
            {
                activeDownloads.Remove(download);
            }
        }

        public BlankPage()
        {
            this.InitializeComponent();

            /**
             * inDev Function
             * 
             * Loads a wallpaper in the background of the app
             */
            if (Core.SetBackground)
            {
                // Es wird ein Wallpaper in den Hintergrund geladen.
                loadBingWallpaper();
                /**
                //BitmapImage bi = new BitmapImage(new Uri("/Assets/ShareFlyout.jpg", UriKind.RelativeOrAbsolute));
                BitmapImage bi = new BitmapImage(new Uri(@"/Metro_Calc;Assets/ShareFlyout.jpg", UriKind.Relative));
                //new Uri(@"/BediaNV;component/Resources/Recycle.png",·UriKind.Relative);
                ImageBrush img = new ImageBrush();
                img.ImageSource = bi;
                this.AppGrid.Background = img;
                 */
            }
        }
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        /**
         * Add 0-9
         */
        private void AddDigit0(object sender, RoutedEventArgs e)
        {
            addDigit("0");
        }
        private void AddDigit1(object sender, RoutedEventArgs e)
        {
            addDigit("1");
        }
        private void AddDigit2(object sender, RoutedEventArgs e)
        {
            addDigit("2");
        }
        private void AddDigit3(object sender, RoutedEventArgs e)
        {
            addDigit("3");
        }
        private void AddDigit4(object sender, RoutedEventArgs e)
        {
            addDigit("4");
        }
        private void AddDigit5(object sender, RoutedEventArgs e)
        {
            addDigit("5");
        }
        private void AddDigit6(object sender, RoutedEventArgs e)
        {
            addDigit("6");
        }
        private void AddDigit7(object sender, RoutedEventArgs e)
        {
            addDigit("7");
        }
        private void AddDigit8(object sender, RoutedEventArgs e)
        {
            addDigit("8");
        }
        private void AddDigit9(object sender, RoutedEventArgs e)
        {
            addDigit("9");
        }

        /**
         * Change the operand
         */
        private void ChangeOperandToAddition(object sender, RoutedEventArgs e)
        {
            changeOperand(1);
        }
        private void ChangeOperandToSubtraction(object sender, RoutedEventArgs e)
        {
            changeOperand(2);
        }
        private void ChangeOperandToMultiplication(object sender, RoutedEventArgs e)
        {
            changeOperand(3);
        }
        private void ChangeOperandToDivision(object sender, RoutedEventArgs e)
        {
            changeOperand(4);
        }

        private void Calculation(object sender, RoutedEventArgs e)
        {
            /**
             * Berechnet das Ergebnis für die aktuelle Aufgabe
             */
            if (this.CalcResult.Text != "0" && this.CalcNumber.Text != "")
            {
                Double value1 = Convert.ToDouble(this.CalcNumber.Text);
                Double value2 = Convert.ToDouble(this.CalcResult.Text);
                Double result = 0;

                this.CalcNumber.Text = this.CalcResult.Text + this.CalcType.Text + this.CalcNumber.Text;

                switch (Core.Operand)
                {
                    case 1:
                        {
                            result = value1 + value2;
                        } break;
                    case 2:
                        {
                            result = value1 - value2;
                        } break;
                    case 3:
                        {
                            result = value1 * value2;
                        } break;
                    case 4:
                        {
                            result = value1 / value2;
                        } break;
                }

                this.CalcResult.Text = result.ToString();
                changeOperand(5);
                Core.IsCalculated = true;
            }
        }
        private void DeleteOne(object sender, RoutedEventArgs e)
        {
            if(this.CalcResult.Text.Length >= 1 && this.CalcResult.Text != "0")
                this.CalcResult.Text = this.CalcResult.Text.Substring(0, this.CalcResult.Text.Length - 1);

            if (this.CalcResult.Text.Length == 0)
                this.CalcResult.Text = "0";
        }
        private void DeleteAll(object sender, RoutedEventArgs e)
        {
            resetCalc();
        }

        private void AddSignDot(object sender, RoutedEventArgs e)
        {
            if (!Core.ExistsDot)
            {
                this.CalcResult.Text = this.CalcResult.Text + ",";
                Core.ExistsDot = true;
            }
        }
    }
}
